/**
 * @author lvzhiyi
 *
 * @description 锚点 + fixed固定组件
 * @example  <a href="test"></a> ===> <div id="test"></div>
 */

import React, { Component } from 'react';
import { getElementTop, addClass, removeClass } from '../../utils/fn';
import './style.less';
// interface AnchorProps {
//     /**
//      * 距离窗口顶部达到指定偏移量后触发
//      */
//     offsetRange?: number | string;
//     /**
//      * 节点固定后的回调
//      */
//     fixedHandle?: Function;
//     /**
//      * active节点的class
//      */
//     activeCls?: string;
// }

class Anchor extends Component<AnchorProps> {
    static defaultProps = {
        offsetRange: 0
    };
    constructor(props: any) {
        super(props);
        this.init = this.init.bind(this);
    }
    anchorListNode: any;
    refs: any;
    init() {
        const anchorNode = this.anchorListNode;
        const { offsetRange, fixedHandle, activeCls } = this.props;
        let fixedTop = 0,
            anchorHeight = 0;
        setTimeout(() => {
            anchorHeight = anchorNode.offsetHeight;
            fixedTop = getElementTop(anchorNode);
        }, 0);
        let anchorListToTop = [];
        const linkNode = anchorNode.getElementsByTagName('a');
        const moveFn = function() {
            const scrollRange = window.pageYOffset;
            let fixedRange = fixedTop - scrollRange;
            if (fixedRange <= 0) {
                anchorNode.nextSibling.style.marginTop = `${anchorHeight}px`;
                anchorNode.style.position = 'fixed';
                fixedHandle && fixedHandle(true);
            } else {
                anchorNode.nextSibling.style.marginTop = 0;
                anchorNode.style.position = 'relative';
                fixedHandle && fixedHandle(false);
            }
            for (let i = 0; i < anchorListToTop.length; i++) {
                let range =
                    anchorListToTop[i] - scrollRange - Number(offsetRange);
                let nextRange =
                    anchorListToTop[i + 1] - scrollRange - Number(offsetRange);
                removeClass(linkNode[i], activeCls);
                if (
                    (range <= 0 && nextRange > 0) ||
                    (i == anchorListToTop.length - 1 && range <= 0)
                ) {
                    addClass(linkNode[i], activeCls);
                }
                if (range > 0) {
                    removeClass(linkNode[i], activeCls);
                }
            }
        };
        for (let i = 0; i < linkNode.length; i++) {
            const ids = linkNode[i].getAttribute('href');
            const AnchorFn = function(e: any) {
                e.preventDefault();
                window.scrollTo(0, anchorListToTop[i] - Number(offsetRange));
                moveFn();
            };
            setTimeout(() => {
                anchorListToTop.push(
                    getElementTop(document.getElementById(ids))
                );
            }, 0);
            linkNode[i].addEventListener('click', AnchorFn, false);
        }
        document.body.addEventListener('touchmove', moveFn, false);
        window.addEventListener('scroll', moveFn, false);
    }
    componentDidMount() {
        this.init();
    }
    render() {
        return (
            <div
                className="anchor-box"
                ref={Anchor => (this.anchorListNode = Anchor)}
            >
                {this.props.children}
            </div>
        );
    }
}

export default Anchor;
